package com.gopay.cron.web.controller;

import com.gopay.common.constants.SubAccountConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.dao.acct.CommonQueryDAO;
import com.gopay.common.domain.cps.transfer.Trans00606VO;
import com.gopay.common.domain.cps.vo.CPSResponse;
import com.gopay.common.domain.fund.vo.PageData;
import com.gopay.common.util.FastJsonUtil;
import com.gopay.common.util.LogUtil;
import com.gopay.remote.order.MainOrderField;
import com.gopay.remote.order.MainOrderUpdateRemoteService;
import com.gopay.scheduler.common.CallCPSHelper;
import com.gopay.scheduler.dao.ReceiptOrderDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Chenyu Li
 * @description
 * @date 2018/3/21
 * Copyright (c) 2017. www.gopay.com.cn Inc.All rights reserved.
 */
@Controller
@RequestMapping("/split")
public class SplitCronController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ReceiptOrderDAO receiptOrderDAO;

    @Resource(name = "comQueryDao")
    private CommonQueryDAO commonQueryDAO;

    @Resource(name = "callCPSHelper")
    private CallCPSHelper callCPSHelper;

    private MainOrderUpdateRemoteService cpsGeneralMainOrderOperClient;

    @Resource(name = "cpsGeneralMainOrderOperClient")
    public void setCpsGeneralMainOrderOperClient(
            MainOrderUpdateRemoteService cpsGeneralMainOrderOperClient) {
        this.cpsGeneralMainOrderOperClient = cpsGeneralMainOrderOperClient;
    }

    /**
     * 用于手动执行延时分账
     * http://localhost:8017/cron/split/doDelay.shtml?key=121
     * 其中key为当前日期的平方
     * @author <a href="mailto:yhwpeng@126.com">Chenyu Li</a>
     * @date 2017-08-11 10:02:52
     */
    @RequestMapping(value="/doDelay",produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String index(HttpServletRequest request) throws Exception {
        PageData pd = new PageData(request);
        LogUtil.info(logger,"页面传入参数为：%s", FastJsonUtil.toJSONString(pd));
        String key = pd.getString("key");
        Calendar now = Calendar.getInstance();
        int day = now.get(Calendar.DAY_OF_MONTH);
        String keyCalc = day * day + "";
        if (!key.equals(keyCalc)) {
            return "key不匹配！";
        }
        try {
            logger.info("延时分账开始查询待分账的网关交易记录!");
            //1.查询一天的待收款分账的记录
            List<Object[]> result = commonQueryDAO.findBySql(buildSplitSql());

            //2.处理结果集
            if(result != null && result.size() > 0){
                logger.info("延时分账待分账的网关支付交易的记录数 = " + result.size());
                for (int i = 0; i < result.size(); i++) {
                        Object[] list = result.toArray();
                        String gopayOrderId = list[i].toString();
                        Trans00606VO vo = new Trans00606VO();
                        //00100的订单号
                        vo.setDtlSq(gopayOrderId);
                        vo.setIsForceRecv(SubAccountConstants.SPLIT_Force_0);
                        vo.setTranCode(IntTxnCd._00606.value);
                        vo.setRemark("收款分账");
                        logger.info("延时分账处理第【" + (i + 1) + "】条记录，调用cps，网关支付交易流水号=" + gopayOrderId);
                        CPSResponse response = callCPSHelper.callByVOTicket(vo);
                        if (!ProcCodeConstants.PROC_CODE_100S1000.equals(response.getRespCode())) {
                            logger.error("------延时分账调用cps返回异常  response=" + response.getRespCode());
                        }
                        logger.info("延时分账第" + (i + 1) + "条处理成功,网关支付交易流水号=" + gopayOrderId);
                    }
                }
            logger.info("延时分账收款分账定时任务结束");
            logger.info("分账订单任务清理开始");
            List<Object[]> result2 = commonQueryDAO.findBySql(buildSyncStaCdSql());
            if(result2 != null && result2.size() > 0) {
                for (int i = 0; i < result2.size(); i++) {
                    Object[] list = result2.get(i);
                    String gopayOrderId = list[0].toString();
                    Map<MainOrderField, String> map = new HashMap<>(5);
                    SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
                    map.put(MainOrderField.TXN_STA_CD, String.valueOf(TxnStaCode.TXN_STA_CD_20001.value));
                    map.put(MainOrderField.LAST_UPDATE_TIME, sf.format(new Date()));
                    map.put(MainOrderField.TRAN_FINISH_TIME, sf.format(new Date()));
                    boolean cleanResult;
                    cleanResult = cpsGeneralMainOrderOperClient.updateMany(gopayOrderId, map);
                    receiptOrderDAO.cleanDelaySplitOrder(gopayOrderId);
                    logger.info("分账订单任务清理结束,清理订单号{}，是否清理成功{}", gopayOrderId, cleanResult);
                    //同时需要将对应的网关订单分账状态置为失败
                    receiptOrderDAO.cleanDelaySplitOrder(list[1].toString());
                }
                logger.info("分账订单任务清理结束,清总条数{}" , result2.size());
            }
        } catch (Exception e) {
            LogUtil.error(logger, e, "【手动触发延时分账】异常");
            return "执行失败！"+ e.getMessage();
        }
        return "成功执行！";
    }

    private String buildSplitSql(){
        String sql = "select a.gopay_order_id  from cps_gen_main_order a left join cps_gen_receipt_order b " +
                "    on a.gopay_order_id = b.gopay_order_id" +
                " where a.txn_sta_cd = 20000" +
                "   and b.OTHER_RECV_STATUS = '1'" +
                "   and b.OTHER_RECV_SYTLE = '2'" +
                "   and a.gopay_int_txn_cd = '00100'" +
                "   and a.gopay_txn_tm > sysdate-30" +
                "   and b.OTHER_RECV_TIME <= to_char(trunc(sysdate),'yyyyMMdd')" +
                "   and b.OTHER_RECV_TIME > to_char(trunc(sysdate-30),'yyyyMMdd')";
        return sql;
    }

    private String buildSyncStaCdSql(){
        String sql = "select b.gopay_order_id, b.relevance_gopay_order_id" +
                "  from cps_gen_main_order a" +
                "  left join cps_gen_main_order b" +
                "    on a.gopay_order_id = b.relevance_gopay_order_id" +
                " where b.txn_sta_cd = '30000'" +
                "   and (a.txn_sta_cd = '20001'" +
                "    or a.txn_sta_cd = '20002' or a.txn_sta_cd = '20003')" +
                "   and a.accounting_point is NULL" +
                "   and b.gopay_int_txn_cd = '00606' and a.gopay_txn_tm > sysdate-50 and b.gopay_txn_tm > sysdate-50";

        return sql;
    }
}

